package com.martin.ads.omoshiroilib.ui;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.imageim.yimirror.R;
import com.imageim.yimirror.base.BaseActivity;
import com.imageim.yimirror.base.BaseApplication;
import com.imageim.yimirror.base.Constants;
import com.imageim.yimirror.bean.analysisPhoto.AnalysisPhotoResultBean;
import com.imageim.yimirror.bean.analysisPhoto.PhotoNoBean;
import com.imageim.yimirror.common.EnviromentConfig;
import com.imageim.yimirror.common.event.EventCode;
import com.imageim.yimirror.common.event.EventMessage;
import com.imageim.yimirror.common.network.NetUtil;
import com.imageim.yimirror.common.network.ThreadPoolManager;
import com.imageim.yimirror.common.network.constants.NetConstants;
import com.imageim.yimirror.common.network.listener.NetCallback;
import com.imageim.yimirror.common.network.tool.ParamCreator;
import com.imageim.yimirror.common.ui.analysis.AnalysisPhotoView;
import com.imageim.yimirror.common.ui.face.DrawFaceView;
import com.imageim.yimirror.common.ui.tip.TipUtil;
import com.imageim.yimirror.common.util.AnimUtil;
import com.imageim.yimirror.common.util.AppUtil;
import com.imageim.yimirror.common.util.CacheUtils;
import com.imageim.yimirror.common.util.FaceDetectManager;
import com.imageim.yimirror.common.util.JsonUtil;
import com.imageim.yimirror.common.util.LogUtil;
import com.imageim.yimirror.common.util.PictureUtils;
import com.imageim.yimirror.common.util.SoundUtil;
import com.imageim.yimirror.common.util.UserUtil;
import com.martin.ads.omoshiroilib.camera.CameraEngine;
import com.martin.ads.omoshiroilib.encoder.MediaCodecUtils;
import com.martin.ads.omoshiroilib.filter.helper.FilterType;
import com.martin.ads.omoshiroilib.flyu.fake.Logger;
import com.martin.ads.omoshiroilib.flyu.fake.LoggerFactory;
import com.martin.ads.omoshiroilib.flyu.hardcode.DemoConstants;
import com.martin.ads.omoshiroilib.flyu.hardcode.HardCodeData;
import com.martin.ads.omoshiroilib.flyu.hardcode.HardCodeHelper;
import com.martin.ads.omoshiroilib.flyu.openglfilter.common.FilterConstants;
import com.martin.ads.omoshiroilib.flyu.openglfilter.detector.DirectionDetector;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.FilterFactory;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.GPUImageFilter;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.GPUImageFilterGroupBase;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.changeface.ChangeFaceInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.changeface.ChangeFaceNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.dstickers.DynamicStickerData;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.dstickers.DynamicStickerMulti;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.GPUImageFilterGroup;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.GPUImageMultiSectionGroup;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.MultiSectionInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.multitriangle.DrawMultiTriangleNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.multitriangle.MultiTriangleInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.CloneFaceFilter;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.SwitchFaceInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.SwitchFaceNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.TwoPeopleSwitch;
import com.martin.ads.omoshiroilib.flyu.sdk.mediaplayer.AudioFocusCore;
import com.martin.ads.omoshiroilib.glessential.CameraView;
import com.martin.ads.omoshiroilib.glessential.GLRootView;
import com.martin.ads.omoshiroilib.ui.face.FaceWrapper;
import com.martin.ads.omoshiroilib.ui.module.EffectsButton;
import com.martin.ads.omoshiroilib.util.BitmapUtils;
import com.martin.ads.omoshiroilib.util.FileUtils;
import com.sdsmdg.tastytoast.TastyToast;
import com.sensetime.stmobileapi.STMobile106;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import static com.martin.ads.omoshiroilib.util.AnimationUtils.displayAnim;

public class CameraPreviewActivity extends BaseActivity implements GPUImageFilterGroupBase.IGroupStateChanged,
        FaceWrapper.FaceDetectResultListener, View.OnClickListener {
    private final static Logger log = LoggerFactory.getLogger();
    private CameraView cameraView;
    private int surfaceWidth, surfaceHeight;
    private boolean canUseMediaCodec;
    private int timeCountDown;
    private TextView timeCountDownText;
    private GLRootView glRootView;

    public static final double preferedRatio = 16.0 / 9;
    private DrawFaceView mDrawFaceView;
    private Handler mHander;
    private boolean isTakingPic;
    private static final int MSG_TAKE_PIC = 100;
    private static final int MSG_GET_ANALYSIS_RESULT = 101;
    private boolean isFaceInValidArea;
    private View ivCamera;
    private TextView tvVersion;
    private int timeCount = 5;
    private TextView tvTimeCount;
    private boolean stopFaceDetect;
    private boolean isUploading;
    private Bitmap photoBitmap;
    private Bitmap faceBitmap;
    private AnalysisPhotoView analysisPhotoView;
    private String photoNo;
    private View btnClose;
    private int analysisCount = 0;

    @SuppressLint("HandlerLeak")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppUtil.setLight(this, 255);
        super.onCreate(savedInstanceState);
        init();
        mHander = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_TAKE_PIC:
                        //                        if (isFaceInValidArea) {
                        //                            takePic();
                        //                        } else {
                        //                            isTakingPic = false;
                        //                        }
                        if (!isFaceInValidArea) {
                            hideTimeCount();
                            return;
                        }
                        tvTimeCount.setVisibility(View.VISIBLE);
                        Animation scale = AnimationUtils.loadAnimation(BaseApplication.getContext(), R.anim.anim_scan_pic_time_scale);
                        scale.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                tvTimeCount.setVisibility(View.INVISIBLE);
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }
                        });
                        scale.setStartOffset(200);
                        tvTimeCount.startAnimation(scale);
                        // 倒计时
                        tvTimeCount.setText(String.valueOf(timeCount));
                        timeCount--;
                        if (timeCount == 0) {
                            if (isFaceInValidArea) {
                                takePic();
                            } else {
                                hideTimeCount();
                            }
                        } else {
                            Message nextMsg = Message.obtain();
                            nextMsg.what = MSG_TAKE_PIC;
                            mHander.removeMessages(MSG_TAKE_PIC);
                            mHander.sendMessageDelayed(nextMsg, 1000);
                        }
                        break;
                    case MSG_GET_ANALYSIS_RESULT:
                        mHander.removeMessages(MSG_GET_ANALYSIS_RESULT);
                        if (analysisCount < 25) {
                            getAnalysisResult();
                            analysisCount++;
                        }
                        break;
                    default:
                }
            }
        };
    } // onCreate

    private void hideTimeCount() {
        timeCount = 5;
        tvTimeCount.setVisibility(View.GONE);
        isTakingPic = false;
    }

    //TODO:change touch logic
    private void init() {
        //        mContext = this;
        //        if (DEBUG)
        //            FilterResourceHelper.generateFilterThumbs(CameraPreviewActivity.this,false);
        //        FileUtils.upZipFile(this,"filter/thumbs/thumbs.zip",getFilesDir().getAbsolutePath());
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //        WindowManager.LayoutParams params = getWindow().getAttributes();
        //        params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        //        getWindow().setAttributes(params);
        //        TipUtil.show("screenWidth=" +screenWidth + ",screenheight=" + screenHeight);
        glRootView = findViewById(R.id.camera_view);
        cameraView = new CameraView(this, glRootView, preferedRatio);
        cameraView.setScreenSizeChangedListener(new CameraView.ScreenSizeChangedListener() {
            @Override
            public void updateScreenSize(int width, int height) {
                surfaceWidth = width;
                surfaceHeight = height;
            }
        });

        mDrawFaceView = new DrawFaceView(this);
        int cHeight = 0;
        int cWidth = 0;
        if (EnviromentConfig.IS_LANDSCAPE) {
            cHeight = screenHeight;
            cWidth = (int) (screenHeight * (1 / CameraEngine.preferredRatio));
        } else {
            cWidth = screenWidth;
            cHeight = (int) (screenWidth * CameraEngine.preferredRatio);
        }
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(cWidth, cHeight);
        lp.addRule(RelativeLayout.CENTER_IN_PARENT);
        mDrawFaceView.setLayoutParams(lp);
        RelativeLayout root = findViewById(R.id.root);
        root.addView(mDrawFaceView, 1);

        //        filterListView =  findViewById(R.id.filter_list);
        //        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        //        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //        filterListView.setLayoutManager(linearLayoutManager);
        //
        //        List<FilterType> filterTypeList = new ArrayList<>();
        //        for (int i = 0; i < FilterType.values().length; i++) {
        //            filterTypeList.add(FilterType.values()[i]);
        //            if (i == 0) filterTypeList.add(FilterType.NONE);
        //        }
        //        FilterAdapter filterAdapter = new FilterAdapter(this, filterTypeList);
        //        filterListView.setAdapter(filterAdapter);
        //        filterAdapter.setOnFilterChangeListener(new FilterAdapter.OnFilterChangeListener() {
        //            @Override
        //            public void onFilterChanged(FilterType filterType) {
        //                cameraView.getGlRender().switchLastFilterOfCustomizedFilters(filterType);
        //            }
        //        });

        initButtons();
        //        cameraSettingsFrag = findViewById(R.id.rl_camera_setting_content);
        //        cameraSettingsFrag.setVisibility(View.GONE);
        //        bottomControlPanel = findViewById(R.id.bottom_control_panel);

        canUseMediaCodec = MediaCodecUtils.checkMediaCodecVideoEncoderSupport() == MediaCodecUtils.CODEC_SUPPORTED
                &&
                MediaCodecUtils.checkMediaCodecAudioEncoderSupport() == MediaCodecUtils.CODEC_SUPPORTED;
        //        recordButton.setRecordable(canUseMediaCodec);

        timeCountDownText = findViewById(R.id.tv_frag_camera_time_lapse_number);

        HardCodeHelper.decompressAllResource(this);
        //        effectListView = findViewById(R.id.effect_list);
        //        LinearLayoutManager linearLayoutManager2 = new LinearLayoutManager(this);
        //        linearLayoutManager2.setOrientation(LinearLayoutManager.HORIZONTAL);
        //        effectListView.setLayoutManager(linearLayoutManager2);
        //        EffectAdapter effectAdapter = new EffectAdapter(this, HardCodeData.itemList);
        //        effectListView.setAdapter(effectAdapter);
        //        effectAdapter.setOnEffectChangeListener(new EffectAdapter.OnEffectChangeListener() {
        //            @Override
        //            public void onFilterChanged(HardCodeData.EffectItem effectItem) {
        //                doUpdateFilter(effectItem);
        //            }
        //        });
        initUIandEvent();
        // abcde美颜级别依次减弱
        cameraView.getGlRender().switchLastFilterOfCustomizedFilters(FilterType.BEAUTIFY_A);
        //        initCovers();
        tvVersion = findViewById(R.id.tv_version);
        tvVersion.setText(AppUtil.getVersionName(mContext));
        showCameraAnim();
    }

    //    private void initCovers() {
    //        ImageView coverLeftView = findViewById(R.id.cover_top);
    //        ImageView coverRightView = findViewById(R.id.cover_bottom);
    //        if (!EnviromentConfig.IS_LANDSCAPE) {
    //            coverLeftView.setVisibility(View.GONE);
    //            coverRightView.setVisibility(View.GONE);
    //        }
    //        int redPacketWidth = (int) ((screenWidth - screenHeight * (1/preferedRatio)) / 2);
    //        int redPacketHeight = screenHeight;
    //        RelativeLayout.LayoutParams lpLeft = new RelativeLayout.LayoutParams(redPacketWidth, redPacketHeight);
    //        coverLeftView.setLayoutParams(lpLeft);
    //        RelativeLayout.LayoutParams lpRight = new RelativeLayout.LayoutParams(redPacketWidth, redPacketHeight);
    //        lpRight.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    //        coverRightView.setLayoutParams(lpRight);
    //        coverLeftView.setImageResource(R.drawable.scan_left);
    //        coverRightView.setImageResource(R.drawable.scan_right);
    //    }

    private void initButtons() {
        cameraView.setRootViewClickListener(new CameraView.RootViewClickListener() {
            @Override
            public void onRootViewTouched(MotionEvent e) {
                //                displayFocusAnim(e);
            }

            @Override
            public void onRootViewClicked() {
            }

            @Override
            public void onRootViewLongClicked() {
                //                if (cameraTouchBtn.isSelected()) {
                //                    requestTakePicture();
                //                }
            }
        });

        btnClose = findViewById(R.id.btn_close);
        btnClose.setOnClickListener(this);
    }

    @Override
    public void onEventMainThread(EventMessage event) {
        super.onEventMainThread(event);
        switch (event.getCode()) {
            case EventCode.CODE_FINISH:
                finish();
                break;
            case EventCode.CODE_HIDE_CAMERA_ANIM:
                AnimUtil.scaleToDismiss(ivCamera);
                break;
            default:
        }
    }

    private void takePic() {
        //        cameraView.getGlRender().stopFaceDetector();
        //        showLoading();
        cameraView.getGlRender().addRunnableOnDrawEnd(new Runnable() {
            @Override
            public void run() {
                BitmapUtils.sendImage(
                        surfaceWidth,
                        surfaceHeight,
                        mContext,
                        new FileUtils.FileSavedCallback() {
                            @Override
                            public void onFileSaved(final String filePath) {
                                hideTimeCount();
                                stopFaceDetect = true;
                                new AsyncTask<Void, Void, Bitmap>() {

                                    @Override
                                    protected Bitmap doInBackground(Void... voids) {
                                        photoBitmap = PictureUtils.getImage(filePath);
                                        faceBitmap = FaceDetectManager.getInstance().getBigestFace(photoBitmap);
                                        String faceStr = BitmapUtils.bitmapToBase64(faceBitmap, 100);
                                        CacheUtils.setString(mContext, Constants.FACE_STR, faceStr);
                                        return faceBitmap;
                                    }

                                    @Override
                                    protected void onPostExecute(Bitmap bitmap) {
                                        if (bitmap == null) {
                                            stopFaceDetect = false;
                                            hideTimeCount();
                                        }
                                    }
                                }.executeOnExecutor(ThreadPoolManager.getInstance().getThreadPool());
                                // 释放相机，并显示分析视图
                                releaseCamera();
                                showAnalysisPhotoView(filePath);
                                btnClose.setVisibility(View.INVISIBLE);
                                // 上传用户照片，获取唯一的photoId
                                uploadUserPhoto();
                            }
                        }
                );
            }
        });
    }

    private void showAnalysisPhotoView(String photoPath) {
        analysisPhotoView.setPhoto(photoPath);
        analysisPhotoView.show();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (cameraView != null) {
            cameraView.onPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (cameraView != null) {
            cameraView.onResume();
        }
        isTakingPic = false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseCamera();
        mContext = null;
        if (mDrawFaceView != null) {
            mDrawFaceView.finish();
        }
        analysisPhotoView.destory();
        if (mHander != null) {
            mHander.removeCallbacksAndMessages(null);
        }
    }

    private void releaseCamera() {
        mDrawFaceView.stopDraw();
        if (cameraView != null) {
            cameraView.onDestroy();
        }
        if (glRootView != null) {
            glRootView.destroyDrawingCache();
        }
        deInitUIandEvent();
    }

    @Override
    protected void initBundle() {
    }

    @Override
    protected int getLayoutId() {
        return R.layout.camera_preview;
    }

    @Override
    protected void initView() {
        tvTimeCount = findViewById(R.id.tv_time_count);
        tvTimeCount.setVisibility(View.INVISIBLE);
        analysisPhotoView = findViewById(R.id.panel_analysis_photo);
    }

    private String photoStr = null;

    private void uploadUserPhoto() {
        if (!isUploading && photoBitmap != null) {
            isUploading = true;
            new AsyncTask<Void, Void, String>() {

                @Override
                protected String doInBackground(Void... voids) {
                    if (photoBitmap != null && photoStr == null) {
                        photoStr = BitmapUtils.bitmapToBase64(photoBitmap, 90);
                    }
                    UserUtil.setImageForBase64(Constants.SEARCH_IMAGE_FOR_IMAGE, photoStr);
                    return photoStr;
                }

                @Override
                protected void onPostExecute(String photoStr) {
                    upload(photoStr);
                }
            }.executeOnExecutor(ThreadPoolManager.getInstance().getThreadPool());
        } //
    }

    //    private void upload(final String photoStr) {
    //        List<BasicNameValuePair> params = new ParamCreator().add("userPhoto", photoStr).build();
    //        NetUtil.postObject(mContext, NetConstants.URL.UPLOAD_SCAN_USER_PHOTO, params, new NetCallback<UploadPhotoResultBean>() {
    //            @Override
    //            public void onStart() {
    //            }
    //
    //            @Override
    //            public void onSuccess(UploadPhotoResultBean result) {
    //                //                hideLoading();
    //                if (result.getGender() == 2) { // female
    //
    //                    if (result.getUserId() != null) {
    //                        UserUtil.setUserId(result.getUserId());
    //                    }
    //
    //                    //保存用户使用次数、推荐编号用来获取推荐服装、新老用戶標簽、是否做過體驗報告測試題
    //                    UserUtil.setUserFlag(result.getFlag());
    //                    UserUtil.setRecommenNo(result.getRecommendNo());
    //                    UserUtil.setUseNo(result.getUseNo());
    //                    UserUtil.setExperienceReportFlag(result.getExperienceReportFlag());
    //
    //                    //  从风格推荐页面重新测试
    //                    if (UserUtil.getAgainIntoStylePage()) {
    //                        Bundle data = new Bundle();
    //                        data.putInt(Constants.STYLE_TYPE, UserUtil.getStyleType());
    //                        SceneManager.toScene(mContext, StyleRecommendActivity.class, data);
    //                        UserUtil.setAgainIntoStylePage(false);
    //                    } else {
    //                        //第一次进入
    //                        UserUtil.setStyleType(0);
    //                        UserUtil.setAgainIntoStylePage(false);
    //                        //SceneManager.toScene(mContext, DailyRecommendActivity.class, null);
    //                        SceneManager.toScene(mContext, ImageManageActivity.class, null);
    //                        String faceStr = BitmapUtils.bitmapToBase64(faceBitmap, 100);
    //                        CacheUtils.setString(mContext, "faceStr", faceStr);
    //                        //                        SceneManager.toScene(mContext, ImageManageActivity.class, null);
    //                    }
    //
    //                } else { // male
    //                    SceneManager.toScene(mContext, GenderTipActivity.class, null);
    //                }
    //                isUploading = false;
    //                finish();
    //            }
    //
    //            @Override
    //            public void onFail(int errorCode, String errorMsg) {
    //                TipUtil.show(errorMsg + " " + errorCode);
    //                CommonData.scanUserPhotoStr = photoStr;
    //                UserUtil.setImageForBase64(Constants.SEARCH_IMAGE_FOR_IMAGE, photoStr);
    //                isUploading = false;
    //                SceneManager.toScene(mContext, NoNetworkUploadPhotoActivity.class, null);
    //                finish();
    //            }
    //        }, UploadPhotoResultBean.class);
    //    } // upload

    private void upload(final String photoStr) {
        List<BasicNameValuePair> params = new ParamCreator().add("userPhoto", photoStr).build();
        NetUtil.postObject(mContext, NetConstants.URL.UPLOAD_SCAN_PHOTO, params, new NetCallback<PhotoNoBean>() {
            @Override
            public void onStart() {
            }

            @Override
            public void onSuccess(PhotoNoBean result) {
                LogUtil.d("data", "photoNo : " + JsonUtil.gson.toJson(result));
                photoNo = result.getPhotoNo();
                UserUtil.setPhotoNo(photoNo);
                mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 1900);
            }

            @Override
            public void onFail(int errorCode, String errorMsg) {
                TipUtil.show(errorMsg + errorCode);
            }
        }, PhotoNoBean.class);
    } // upload

    /**
     * 获取照片分析结果
     */
    private void getAnalysisResult() {
        List<BasicNameValuePair> params = new ParamCreator().add("photoNo", photoNo).build();
        NetUtil.getObject(mContext, NetConstants.URL.GET_ANALYSIS_PHOTO_RESULT, params, new NetCallback<AnalysisPhotoResultBean>() {
            @Override
            public void onStart() {
                LogUtil.d("data", "getAnalysisResult");
            }

            @Override
            public void onSuccess(AnalysisPhotoResultBean result) {
                LogUtil.d("data", "analysis result : " + JsonUtil.gson.toJson(result));
                int gender = result.getGender();


                if (result.getIfAll() == 1 || result.getIfAll() == 2) { // 正在分析或正确分析完成
                    analysisPhotoView.setData(result);
                    if (result.getIfAll() == 2) {
                        // TODO
                        UserUtil.setUserId(result.getUserId());
                    }
                } else if (result.getIfAll() == 3) { // 无法分析
                }

                if (result.getIfAll() != 2 && result.getIfAll() != 3) {
                    if (mHander != null) {
                        mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 500);
                    }
                }
            }

            @Override
            public void onFail(int errorCode, String errorMsg) {
                if (errorCode == 1000) {
                    if (mHander != null) {
                        mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 500);
                    }
                } else {
                    TipUtil.show(errorMsg + errorCode);
                }
            }
        }, AnalysisPhotoResultBean.class);
    }


    private void showCameraAnim() {
        ivCamera = findViewById(R.id.iv_anim_camera);
        AnimUtil.scaleUp(ivCamera);
    }

    @Override
    protected void initData() {
        playSound();
    }

    private void playSound() {
        int index = new Random().nextInt(3);
        switch (index) {
            case 0:
                SoundUtil.play(R.raw.a001);
                break;
            case 1:
                SoundUtil.play(R.raw.a002);
                break;
            case 2:
                SoundUtil.play(R.raw.a003);
                break;
            default:
        }
    }

    private void showHint(final String hint) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TastyToast.makeText(getApplicationContext(), hint, TastyToast.LENGTH_LONG,
                        TastyToast.INFO);
            }
        });
    }

    private EffectsButton getEffectsBtn(int id) {
        return (EffectsButton) findViewById(id);
    }

    private TextView getTextView(int id) {
        return (TextView) findViewById(id);
    }

    @Override
    public void onFaceInfoList(final STMobile106[] faceInfoList) {
        //        logD("faceInfoList=" + String.valueOf(faceInfoList));
        //        if (faceInfoList != null) {
        //            for (int i = 0; i < faceInfoList.length; i++) {
        //                logD("facePos:   " + faceInfoList[i].getRect().left + "," + faceInfoList[i].getRect().top + ",  "
        //                        + faceInfoList[i].getRect().redPacketWidth() + "," + faceInfoList[i].getRect().redPacketHeight());
        //            }
        //        }
        if (stopFaceDetect) {
            mDrawFaceView.setFaceInfoList(null);
            return;
        } else {
            mDrawFaceView.setFaceInfoList(faceInfoList);
        }
        // -----------------------------------------------------
        //        synchronized (mDrawFaceView) {
        STMobile106 maxFace = null; // 最大的并且在有效画面区域的人脸
        if (faceInfoList != null && faceInfoList.length > 0) {
            if (faceInfoList.length > 1) {
                List<STMobile106> faceList = Arrays.asList(faceInfoList);
                Collections.sort(faceList, mDrawFaceView.faceSizeComparator);
                for (int i = 0; i < faceList.size(); i++) {
                    if (mDrawFaceView.isFaceInValidArea(faceList.get(i))) {
                        maxFace = faceList.get(i);
                        break;
                    }
                }
            } else { // Only checked one face.
                if (mDrawFaceView.isFaceInValidArea(faceInfoList[0])) {
                    maxFace = faceInfoList[0];
                }
            }
        }
        // lock
        if (faceInfoList != null && faceInfoList.length > 0) {
            isFaceInValidArea = (maxFace != null);
            //                isFaceInValidArea = mDrawFaceView.isFaceInValidArea(faceInfoList[0]);
            if (isFaceInValidArea && !isTakingPic) {
                isTakingPic = true;
                Message msg = new Message();
                msg.what = MSG_TAKE_PIC;
                mHander.removeMessages(MSG_TAKE_PIC);
                mHander.sendMessageDelayed(msg, 600);
            }
        } else {
            isFaceInValidArea = false;
            isTakingPic = false;
        }
        //        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_close:
                finish();
                break;
            default:
        }
    }

    class CameraSettingBtn {
        EffectsButton effectsButton;
        TextView hintText;

        CameraSettingBtn(int btnId, int textId) {
            effectsButton = getEffectsBtn(btnId);
            hintText = getTextView(textId);
        }

        boolean isSelected() {
            return effectsButton.isSelected();
        }

        void changeState() {
            if (!effectsButton.isSelected()) {
                effectsButton.setSelected(true);
                hintText.setTextColor(mContext.getResources().getColor(R.color.app_color));
            } else {
                effectsButton.setSelected(false);
                hintText.setTextColor(Color.WHITE);
            }
        }

        CameraSettingBtn register(EffectsButton.OnClickEffectButtonListener listener) {
            effectsButton.setOnClickEffectButtonListener(listener);
            return this;
        }
    }

    @SuppressLint("HandlerLeak")
    final Handler timeCountDownHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    timeCountDown--;
                    if (timeCountDown > 0) {
                        timeCountDownText.setText("" + timeCountDown);
                        displayAnim(timeCountDownText, mContext, R.anim.anim_text_scale, View.VISIBLE);
                        Message message = timeCountDownHandler.obtainMessage(1);
                        timeCountDownHandler.sendMessageDelayed(message, 1000);      // send message
                    } else {
                        timeCountDownText.setVisibility(View.GONE);
                        takePic();
                    }
                default:
            }
            super.handleMessage(msg);
        }
    };


    protected DirectionDetector mDirectionDetector;

    protected GPUImageFilterGroupBase mCurrentFilter;

    private int mMaxFaceCount = 5;

    private FaceWrapper faceWrapper;

    private void deinitVDM() {
        if (null != mDirectionDetector) {
            mDirectionDetector.stop();
            mDirectionDetector = null;
        }

        if (null != faceWrapper) {
            faceWrapper.uninit();
            faceWrapper = null;
        }
        mCurrentFilter = null;
    }

    private void doUpdateFilter(HardCodeData.EffectItem item) {
        GPUImageFilterGroupBase filterGroup = parseEffect(item.type, DemoConstants.APPDIR + "/" + item.unzipPath);
        filterGroup.setGroupStateChangedListener(this);
        if (null != faceWrapper) {
            mCurrentFilter = filterGroup;
            mCurrentFilter.setPhoneDirection(mDirectionDetector.getDirection());
            faceWrapper.setFilter(mCurrentFilter);
        }

        if (mMaxFaceCount > FilterConstants.MAX_FACE_COUNT) {
            mMaxFaceCount = FilterConstants.MAX_FACE_COUNT;
        }

        if (null != faceWrapper && null != faceWrapper.getGlRender()) {
            faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
        }
    }

    private void doUpdateFaceDetector() {
        if (faceWrapper == null) {
            return;
        }

        if (faceWrapper.getGlRender() == null) {
            return;
        }

        faceWrapper.getGlRender().initFaceDetector();
        faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
    }

    public final static int TYPE_CHANGE_FACE = 0;
    public final static int TYPE_DYNAMIC_STICKER = 1;
    public final static int TYPE_SWITCH_FACE = 2;
    public final static int TYPE_MULTI_SECTION = 3;
    public final static int TYPE_MULTI_TRIANGLE = 4;  // 注意强制更新的内容
    public final static int TYPE_TWO_PEOPLE_SWITCH = 5;
    public final static int TYPE_CLONE_PEOPLE_FACE = 6;

    protected GPUImageFilterGroupBase parseEffect(int type, String unzipPath) {
        GPUImageFilterGroupBase groupBase = new GPUImageFilterGroup();
        groupBase.addFilter(new GPUImageFilter());
        if (type < 0) {
            return groupBase;
        }
        try {
            if (type == TYPE_CHANGE_FACE) {
                ChangeFaceInfo changeFaceInfo = FilterFactory.readChangeFaceInfo(unzipPath);
                groupBase.addFilter(new ChangeFaceNet(unzipPath, changeFaceInfo));
            } else if (type == TYPE_DYNAMIC_STICKER) {
                DynamicStickerData data = FilterFactory.readDynamicStickerData(unzipPath);
                groupBase.addFilter(new DynamicStickerMulti(unzipPath, data));
            } else if (type == TYPE_SWITCH_FACE) {
                SwitchFaceInfo switchFaceInfo = FilterFactory.readSwitchFaceData(unzipPath);
                groupBase.addFilter(new SwitchFaceNet(unzipPath, switchFaceInfo));
            } else if (type == TYPE_MULTI_SECTION) {
                MultiSectionInfo multiSectionInfo = FilterFactory.readMultiSectionData(unzipPath);
                groupBase = new GPUImageMultiSectionGroup(unzipPath, multiSectionInfo);
                groupBase.addFilter(new GPUImageFilter());
            } else if (type == TYPE_MULTI_TRIANGLE) {
                MultiTriangleInfo info = FilterFactory.readMultiTriangleInfo(unzipPath);
                groupBase.addFilter(new DrawMultiTriangleNet(unzipPath, info));
            } else if (type == TYPE_TWO_PEOPLE_SWITCH) {
                groupBase.addFilter(new TwoPeopleSwitch());
            } else if (type == TYPE_CLONE_PEOPLE_FACE) {
                groupBase.addFilter(new CloneFaceFilter());
            }
        } catch (IOException e) {
            log.error("read effect filter data failed, " + e.getMessage());
        } catch (JSONException e) {
            log.error("parse effect filter data failed, " + e.getMessage());
        }
        return groupBase;
    }

    protected void initUIandEvent() {
        // init faceu related
        AudioFocusCore.initialize(mContext);
        mCurrentFilter = new GPUImageFilterGroup();
        mCurrentFilter.addFilter(new GPUImageFilter());
        if (null == mDirectionDetector) {
            mDirectionDetector = new DirectionDetector(this, false);
            mDirectionDetector.start();
        }
        // GPUVideoViewDecorator 是先做的翻转，再做的旋转
        faceWrapper = new FaceWrapper(this, cameraView.getGlRender());
        faceWrapper.setDirectionDetector(mDirectionDetector);
        faceWrapper.setFaceDetectResultListener(this); // face detect listener
        faceWrapper.getGlRender().setUpCamera(cameraView.getCameraEngine().getDisplayRotate(),
                cameraView.getGlRender().isCameraFacingFront(), true);

        doUpdateFilter(HardCodeData.itemList.get(0));
        doUpdateFaceDetector();
    }

    int rotateIndex = 0;
    boolean isHorizontalFilp = false;
    boolean isVerticalFilp = false;
    int currAngel = 0;

    public void rotateCamera(View v) {
        int direction = 0;
        switch (rotateIndex % 4) {
            case 0:
                currAngel = 0;
                direction = 0;
                break;
            case 1:
                currAngel = 90;
                direction = 1;
                break;
            case 2:
                currAngel = 180;
                direction = 2;
                break;
            case 3:
                currAngel = 270;
                direction = 3;
                break;
            default:
        }
        //        faceWrapper.getGlRender().setUpCamera(currAngel,
        //                isHorizontalFilp, isVerticalFilp);
        rotateIndex++;
        //        TipUtil.show("currAngel=" + currAngel);

        faceWrapper.setFaceDirection(direction);
        TipUtil.show("direction=" + direction);
    }


    public void flipHorizontal(View v) {
        isHorizontalFilp = !isHorizontalFilp;
        faceWrapper.getGlRender().setUpCamera(currAngel,
                isHorizontalFilp, isVerticalFilp);
        TipUtil.show("isVerticalFilp=" + isVerticalFilp);
        TipUtil.show("isHorizontalFilp=" + isHorizontalFilp);
    }

    public void flipVertical(View v) {
        isVerticalFilp = !isVerticalFilp;
        faceWrapper.getGlRender().setUpCamera(currAngel,
                isHorizontalFilp, isVerticalFilp);
        TipUtil.show("isVerticalFilp=" + isVerticalFilp);
        TipUtil.show("isHorizontalFilp=" + isHorizontalFilp);
    }


    protected void deInitUIandEvent() {
        deinitVDM();
    }

    @Override
    public void onTipsAndCountChanged(int maxCount, final String tips, final int duration) {
        mMaxFaceCount = maxCount;
        if (null != faceWrapper && null != faceWrapper.getGlRender()) {
            faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
        }
        log.debug("onTipsAndCountChanged " + maxCount + " " + tips + " " + duration);
    }

//    public void checkUpgrade(View v) {
//        Beta.checkUpgrade(true, false);
//    }

    @Override
    public boolean isSupportSwipeBack() {
        return false;
    }

    @Override
    protected boolean isSupportAutoQuit() {
        return true;
    }

}
